package com.apo1o.cmscore.controller;


import com.apo1o.cmscore.bean.ext.CategoryExtend;
import com.apo1o.cmscore.dao.ArticleDao;
import com.apo1o.cmscore.dao.CategoryDao;
import com.apo1o.cmscore.exception.ServiceException;
import com.apo1o.cmscore.util.Result;
import com.apo1o.cmscore.util.ResultCode;
import com.apo1o.cmscore.util.excel.CategoryListener;
import com.apo1o.cmscore.util.excel.CategoryParentIdConverter;
import com.apo1o.cmscore.util.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;

import com.apo1o.cmscore.service.ICategoryService;
import com.apo1o.cmscore.bean.Category;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Apo1o
 * @since 2023-11-15
 */
@Api(tags = "栏目模块")
@RestController
@RequiredArgsConstructor
@RequestMapping("auth/category")
public class CategoryController {
    private final ICategoryService categoryService;
        private  final CategoryDao categoryDao;
        private  final ArticleDao articleDao;
        private final ExcelUtil excelUtil;
    @ApiOperation(value = "新增栏目", notes = "栏目名必须唯一，如果为二级栏目则其父栏目id必须有效")
    @PostMapping("/save")
    public Result saveOrUpdate(@RequestBody Category category) {
        //1.判断 栏目名是否唯一
        LambdaQueryWrapper<Category> qw = new LambdaQueryWrapper<>();
        qw.eq(Category::getName, category.getName());
        Category c = categoryDao.selectOne(qw);
        if (c != null)
            throw new ServiceException(ResultCode.CATEGORYNAME_HAS_EXISTED);

        //2.如果包含父栏目，则判断parentId是否有效
        Integer parentId = category.getParentId();
        if (parentId != null && categoryDao.selectById(parentId) == null)
            throw new ServiceException(ResultCode.PARAM_IS_INVALID);

        //3.获取max(order_num)
        // 栏目表中无数据，新插入栏目序号为1
        int order_num = 1;
        // 栏目表中有数据，新插入栏目序号 = max(order_num) + 1;
        if (categoryDao.selectCount(null) != 0) {

            //借助自定义sql语句实现，【简单，推荐】
            Integer mo = categoryDao.getMaxOrderNum();
            System.out.println("max_order_num: " + mo);

            order_num = mo + 1;
        }

        //4.设置order_num值
        category.setOrderNum(order_num);

        //5.插入
        categoryDao.insert(category);
        return Result.success("新增成功");
    }

    @ApiOperation("根据id删除")
    @DeleteMapping("/deleteById/{id}")
    public Result deleteById(@PathVariable  Integer id) {
        //1.栏目id判断
        Category category = categoryDao.selectById(id);
        if (category == null)
            throw new ServiceException(ResultCode.CATEGORY_NOT_EXIST);

        //2.栏目级别判断
        if (category.getParentId() == null) {
            //一级栏目
            // 2.1 如果该1级栏目下存在2级栏目，删除失败
            // select count(*) from cms_category where deleted = 0 and parent_id = ? ;
            LambdaQueryWrapper<Category> qw = new LambdaQueryWrapper<>();
            qw.eq(Category::getParentId, id);
            if (categoryDao.selectCount(qw) > 0)
                throw new ServiceException(ResultCode.PARAM_IS_INVALID);
        } else {
            //二级栏目
            // 2.2 如果2级栏目下不存在任何资讯，可以删除成功
            // select count(*) from cms_article where deleted = 0 and category_id = ?

            // 2.3 如果2级栏目下存在资讯，且发表资讯的用户存在(未删除状态)，则删除失败
            Integer num = articleDao.getArticleNumByCategoryId(id);
            if (num > 0)
                throw new ServiceException(ResultCode.PARAM_IS_INVALID);
        }

        //3.栏目删除
        categoryDao.deleteById(id);
    categoryService.removeById(id);
        return Result.success();
    }

    @ApiOperation("批量删除")
    @PostMapping("/deleteByIdAll/{ids}")
    public Result deleteBatch(@PathVariable("ids") List<Integer> ids) {

    categoryService.removeByIds(ids);
        return Result.success();
    }

    @ApiOperation("基本查询")
    @GetMapping("/findAll")
    public Result findAll() {
        return Result.success(categoryService.list());
    }

    @ApiOperation("根据id查询")
    @GetMapping("/getCategoryById/{id}")
    public Result findOne(@PathVariable  Integer id) {
        return Result.success(categoryDao.selectById(id));
    }

    @ApiOperation("更新")
    @PutMapping("update")
    public Result update(@RequestBody Category category){
        if (categoryDao.selectById(category.getId())==null){
            return Result.failure(ResultCode.DATA_NONE);
        }
        categoryDao.updateById(category);
        return Result.success("更新成功");

    }
    @ApiOperation(value = "分页查询所有栏目")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前页", dataType = "int", required = true, defaultValue = "1", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "int", required = true, defaultValue = "4", paramType = "query"),
            @ApiImplicitParam(name = "parentId", value = "父栏目id", dataType = "int", paramType = "query")
    })
    @GetMapping("/query")
    public Result findPage(Integer pageNum, Integer pageSize,  Integer parentId) {

        IPage<Category> p = categoryService.query(pageNum, pageSize, parentId);
        return Result.success(p);
    }
    @ApiOperation(value = "查询所有1级栏目(含2级)", notes = "不需要分页")
    @GetMapping("/queryAllParent")
    public Result queryAllParent() {
        List<CategoryExtend> list = categoryService.queryAllParent();

        return Result.success(list);
    }
    @ApiOperation("获取所有父栏目")
    @GetMapping("/queryAllOneLevel")
    public Result queryAllParentWithoutTwo() {
        List<Category> list = categoryService.queryAllOneLevel();
        return Result.success(list);
    }

    @ApiOperation("导入栏目数据")
    @PostMapping( "/import")
    public Result imports(@RequestPart MultipartFile file) {
        //导入前,更新一级栏目集合,防止在导入前数据库中的一级栏目被更新
        CategoryParentIdConverter.list = categoryService.queryAllOneLevel();
        //获取数据
        List<Category> list = excelUtil.importData(file, Category.class, new CategoryListener());
        //导入数据到数据库中
        list.forEach(e-> categoryDao.insert(e));


        return Result.success("数据导入成功");
    }
    @ApiOperation("导出栏目数据")
    @GetMapping(value = "/export", produces = "application/octet-stream")
    public void exports(HttpServletResponse response) {
        //导出前,更新一级栏目集合,防止在导出前数据库中的一级栏目被更新
        CategoryParentIdConverter.list = categoryService.queryAllOneLevel();
        //1.获取栏目数据
        List<Category> list = categoryService.queryAll();
        //2.导出数据
        excelUtil.exportExcel(response, list, Category.class, "栏目信息表");
    }

}

